iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0
自我挑戰組

學習JavaScript的基礎概念系列 第 30

Day30 ToDoList - 3 & 自我挑戰感想

  • 分享至 

  • xImage
  •  

感想
長達30天的自我挑戰要結束了,其實內心也有點不捨,也感謝這挑戰給了我許多查資料的動力,當道某些講解看不懂就再找其他講解,直到一己看懂,也喜歡自己那份投入的心情。對我來說第30天不是結束,而是馬拉松賽跑的其中一個里程碑,期望自己還有看到這篇文章的你,也保持那股動力持續地走下去。
有些篇章因為時間關係準備的資料不夠齊全,因此我會繼續編輯更新!


製作ToDoList流程-3

  • 讓文字資料保留在Local Storage
  • 讓Local Storage資料展示在網頁
  • 按「清除」按鈕時也能刪掉local Storage的項目,搭配splice()
  • 根據日期作排列 (目前還有點bug,會再持續修改)
  • 驗證看是否有做排列
  • 按下sort by time按鈕根據日期作排列
  • 規劃CSS樣式

資料補充:
Math.floor():函式會回傳小於等於所給數字的最大整數。
slice():方法會回傳一個新陣列物件,為原陣列選擇之 begin 至 end(不含 end)部分的淺拷貝(shallow copy)。而原本的陣列將不會被修改。

讓文字資料保留Local Storage

//建立一個物件,可以放todo的資料
    let myTodo = {
        todoText:todoText,
        todoMonth:todoMonth,
        todoDate:todoDate
    }

    //把輸入的資料放進Local Storage,陣列裡面再放todo資料物件
    let myList = localStorage.getItem("list");

    //如果key是空的,就加入myTodo物件進空陣列,並且用JSON.stringify()轉換成字串
    if (myList == null) {
        localStorage.setItem("list",JSON.stringify([myTodo]));
    } else {
        //如果key不是空,就把value用JSON.parse()轉換成陣列
            let myListArray = JSON.parse(myList);
            //把新增的資料推進myTodo物件
            myListArray.push(myTodo);
            //再將它轉換成字串,才能顯示在Storage
            localStorage.setItem("list",JSON.stringify(myListArray));
    };
    console.log(myTodo);

https://ithelp.ithome.com.tw/upload/images/20221014/20152070x87h3hUI5D.png
https://ithelp.ithome.com.tw/upload/images/20221014/20152070u3G9aKkB3a.png

讓Local Storage資料展示在網頁

loadData();

function loadData(){

    // 讓Local Storage資料展示在網頁 
    let myList = localStorage.getItem("list");

    // 如果key不等於空 
    if (myList !== null) { 
        let myListArray = JSON.parse(myList);

        myListArray.forEach((item)=>{
            //建立todo 
            let todo = document.createElement("div"); 
            todo.classList.add("todo"); 
            let text= document.createElement("p"); 
            text.classList.add("todo-text"); 
            text.innerText = item.todoText; 
            let time = document.createElement("p"); 
            time.classList.add("todo-time"); 
            time.innerText = item.todoMonth + " / " + item.todoDate;

            //看item有什麼 
            console.log(item); 
            console.log("item.todoText: " + item.todoText); 
            console.log("item.todoMonth: " + item.todoMonth); 
            console.log("item.todoDate: " + item.todoDate); 
            todo.appendChild(text); 
            todo.appendChild(time);

            //建立勾勾和垃圾桶 
            let completeButton = document.createElement("button"); 
            completeButton.classList.add("complete"); 
            completeButton.innerHTML = '<i class="fa-regular fa-check"></i>'; 
            //按下勾勾按鈕時的動作     
            completeButton.addEventListener("click", (e)=>{ 
                //找父元素 
                let todoItem = e.target.parentElement; 
                //按下時新增class 
                todoItem.classList.toggle("done"); 
            }) 
            let trashButton = document.createElement("button"); 
            trashButton.classList.add("trash"); 
            trashButton.innerHTML = '<i class="fa-light fa-trash"></i>'; 
            trashButton.addEventListener("click", (e)=>{ 
                //找父元素 
                let todoItem = e.target.parentElement; 
                //動畫先執行完,才會執行這個callback function 
                todoItem.addEventListener("animationend",()=>{

                    //讓這裡也能刪掉local Storage的項目 
                    let text = todoItem.children[0].innerText; 
                    let myListArray = JSON.parse(localStorage.getItem("list")); 
                    myListArray.forEach((item, index)=>{ 
                        if(item.todoText == text){ 
                            //.splice()刪除目前既有元素 
                            myListArray.splice(index,1); 
                            //更新Local Storage 
                            localStorage.setItem("list",JSON.stringify(myListArray)); 
                        } 
                    }) 
                    //清除目前的父元件 
                    todoItem.remove(); 
                }) 
                todoItem.style.animation = "scaleDown 0.3s forwards" 
            }) 
            //勾勾和垃圾桶加到todo裡 
            todo.appendChild(completeButton); 
            todo.appendChild(trashButton);

            //把建立的todo放入section 
            section.appendChild(todo); 
    }); 
} 
}

如果不清楚myListArray.forEach((item)的item是麼什麼,可以console出來:

    myListArray.forEach((item)=>{ 
        //建立todo 
        let todo = document.createElement("div"); 
        todo.classList.add("todo"); 
        let text= document.createElement("p"); 
        text.classList.add("todo-text"); 
        text.innerText = item.todoText; 
        let time = document.createElement("p"); 
        time.classList.add("todo-time"); 
        time.innerText = item.todoMonth + " / " + item.todoDate; 
        //看item有什麼 
        console.log(item); 
        console.log("item.todoText: " + item.todoText); 
        console.log("item.todoMonth: " + item.todoMonth); 
        console.log("item.todoDate: " + item.todoDate);
    }

console結果:
https://ithelp.ithome.com.tw/upload/images/20221014/20152070aC4tD2Frxx.png

在上方的清除按鈕事件裡也需要加入這一段:
按「清除」按鈕時也能刪掉local Storage的項目,搭配splice()

//讓這裡也能刪掉local Storage的項目 
                let text = todoItem.children[0].innerText; 
                let myListArray = JSON.parse(localStorage.getItem("list")); 
                myListArray.forEach((item, index)=>{ 
                    if(item.todoText == text){ 
                        //.splice()刪除目前既有元素 
                        myListArray.splice(index,1); 
                        //更新Local Storage 
                        localStorage.setItem("list",JSON.stringify(myListArray)); 
                    } 
                })

根據日期作排列:

// 根據日期作排列 
function mergeTime(arr1,arr2){ 
    let result = []; 
    let i = 0; 
    let j = 0;

    while(i < arr1.length && j < arr2.length){ 
        if(Number(arr1[i].todoMonth) > Number(arr2[j].todoMonth)){ 
            result.push(arr1[j]); 
            j++; 
        } else if (Number(arr1[i].todoMonth) < Number(arr2[j].todoMonth)){ 
            result.push(arr1[i]); 
            i++; 
        }else if(Number(arr1[i].todoMonth) == Number(arr2[j].todoMonth)){ 
        //如果月份相同,就比較日期 
            if(Number(arr1[i].todoDate) > Number(arr2[j].todoDate)){ 
                result.push(arr2[j]); 
                j++; 
            } else { 
                result.push(arr1[i]); 
                i++; 
            } 
        } 
    } 
    console.log("我是arr1:"); 
    console.log(arr1); 
    console.log("我是arr2:"); 
    console.log(arr2); 
    console.log("我是arr1[i]:"); 
    console.log(arr1[i]); 
    console.log("我是arr2[j]:"); 
    console.log(arr2[j]); 
    console.log("i:"); 
    console.log(i); 
    console.log("j:"); 
    console.log(j);

    //如果還是有剩下沒有符合條件的結果,就讓它們全部push到result陣列裡面 
    while(i < arr1.length){ 
        result.push(arr1[i]); 
        i++; 
    } 
    while(j < arr2.length){ 
        result.push(arr2[j]); 
        j++; 
    } 
    return result; 
}

//遞迴演算法 
function mergeSort(arr){ 
    // 如果長度是1就不用做任何事 
    if(arr.length ===1){ 
        return arr; 
    } else { 
        //Math.floor()小於等於的最大整數 
        let middle = Math.floor(arr.length / 2); 
        //用middle作結束 
        let right = arr.slice(0,middle); 
        //用middle作開始 
        let left = arr.slice(middle,arr.length); 
        console.log("我是middle:"); 
        console.log(middle); 
        console.log("我是right:"); 
        console.log(right); 
        console.log("我是left:"); 
        console.log(left); 
        return mergeTime(mergeSort(right),mergeSort(left)); 
    } 
} 
//驗證看是否有做排列 
console.log(mergeSort(JSON.parse(localStorage.getItem("list"))));

按下sort by time按鈕根據日期作排列:

// 按下sort by time按鈕根據日期作排列
let sortButton = document.querySelector("div.sortbtton");

sortButton.addEventListener("click",()=>{

    //排列這些資料,要先找到list
    let sortedArry = mergeSort(JSON.parse(localStorage.getItem("list")));
    //用stringify()轉換資料型態
    localStorage.setItem("list",JSON.stringify(sortedArry));

    //先把它們刪掉,再重新排列一次
    let len = section.children.length;

    for (let i=0;i<len;i++){
        section.children[0].remove();
    }
    //執行讓Local Storage資料展示在網頁的function
    loadData();
});

ToDoList 設計草案(持續規劃中...):
需要再一點時間Q_Q

https://ithelp.ithome.com.tw/upload/images/20221014/20152070t6qj0KBMZf.png


參考資料:

javascript - How can I remove a specific item from an array? - Stack Overflow

Array.prototype.splice() - JavaScript | MDN

Math.floor() - JavaScript | MDN

Array.prototype.slice() - JavaScript | MDN

2022網頁開發全攻略(HTML, CSS, JavaScript, React, SQL, Node, more)

【Day25】[演算法]-合併排序法Merge Sort


上一篇
Day29 來製作ToDoList吧 - 2
系列文
學習JavaScript的基礎概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言